
#include "sciter-x-window.hpp"

#include <functional>
#include <thread>
#include <chrono>

// lvgl
#include "lvgl/lvgl.h"
#include "lvgl_init.h"

void debug(const char* buf) {
    OutputDebugStringA(buf);
}

class frame: public sciter::window {
public:
  frame() : window(SW_TITLEBAR | SW_RESIZEABLE | SW_CONTROLS | SW_MAIN | SW_ENABLE_DEBUG) {}

  int counter = 0;
 
  /* 手表界面鼠标点击事件 */
  void onWatchClick(int x, int y, bool pressed) {
      g_lvglContext_t.mouse_state = pressed ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
      g_lvglContext_t.mouse_point.x = x;
      g_lvglContext_t.mouse_point.y = y;
  }

  /* 手表界面鼠标移动事件 */
  void onWatchMove(int x, int y) {
	  g_lvglContext_t.mouse_point.x = x;
	  g_lvglContext_t.mouse_point.y = y;
  }

  SOM_PASSPORT_BEGIN(frame)
    SOM_FUNCS(
      SOM_FUNC(onWatchClick),
      SOM_FUNC(onWatchMove),
    )
  SOM_PASSPORT_END

  // sample of handling DOM events + sample of window->call_function("scriptFunction",...):
  virtual bool handle_event(HELEMENT, BEHAVIOR_EVENT_PARAMS& params) {
    sciter::dom::element target = params.heTarget;
    switch (params.cmd) {
      case BUTTON_CLICK:
        if (target.test("button#test-script-func-1")) {
          // call free function, passing integer value: 
          sciter::value rv = this->call_function("scriptFunc", ++counter); 
          assert(rv.get<int>() == counter);
          return true;
        }
        else if (target.test("button#test-script-func-2"))
        {
          // call function by its "path", passing script object { data: counter, title: "text" } :
          sciter::value obj;
          obj.set_item("data", ++counter);
          obj.set_item("title", "hello from native side");
          this->call_function("scriptNS.testFunc", obj);
          return true;
        }
        else if (target.test("button#test-script-func-3"))
        {
          // call function by its "path"
          try {
            this->call_function("scriptNS.testErroneousFunc");
          }
          catch (sciter::script_error e) {
             std::string err = e.what();
             if (auto pdo = sciter::debug_output::instance()) {
               pdo->print(err.c_str());
             }
          }
          return true;
        }

    }
    return false;
  }
};

#include "resources.cpp"

int uimain(std::function<int()> run ) {

    lv_init();

    lv_log_register_print_cb(debug);

    lvgl_hal_init();

    // enable features to be used from script
    SciterSetOption(NULL, SCITER_SET_SCRIPT_RUNTIME_FEATURES,
                            ALLOW_FILE_IO |
                            ALLOW_SOCKET_IO |
                            ALLOW_EVAL |
                            ALLOW_SYSINFO );

    sciter::debug_output_console console; // console.log() ->  console window

    // resources archive
    sciter::archive::instance().open(aux::elements_of(resources)); // bind resources[] (defined in "resources.cpp") with the archive

    // set initial script, note it will be run anew on each document instance,
    // *before* document will have its DOM elements.
    sciter::window::set_init_script("globalThis.initializedByInitScript = 42");

    sciter::window::set_variable("initializedByCode", 0xAF);

    sciter::om::hasset<frame> pwin = new frame();

    // example, setting "desktop" media variable, check https://sciter.com/forums/topic/debugging-issues/
    SciterSetMediaType(pwin->get_hwnd(), WSTR("desktop"));

    // note: this:://app URL is dedicated to the sciter::archive content associated with the application
    pwin->load(WSTR("this://app/default.htm"));

    pwin->expand();

    return run();

}
